using System.Collections.Generic;
using System.Threading.Tasks;
using Abp.Application.Services.Dto;
using Abp.Authorization;
using Abp.AutoMapper;
using Abp.Domain.Repositories;
using FutureApp.Authorization;
using FutureApp.Users.Dto;
using Microsoft.AspNet.Identity;

namespace FutureApp.Users
{
    /// <AppService/>
    [AbpAuthorize(PermissionNames.Pages_Users)]
    public class UserAppService : FutureAppAppServiceBase, IUserAppService
    {
        private IRepository<User, long> UserRepository { get; }

        /// <constructor/>
        public UserAppService(IRepository<User, long> userRepository)
        {
            this.UserRepository = userRepository;
        }

        /// <inheritDoc/>
        public async Task ProhibitPermission(ProhibitPermissionInputDto input)
        {
            var user = await this.UserManager.GetUserByIdAsync(input.UserId);
            var permission = this.PermissionManager.GetPermission(input.PermissionName);

            await this.UserManager.ProhibitPermissionAsync(user, permission);
        }

        /// <inheritDoc/>
        public async Task RemoveFromRole(long userId, string roleName)
        {
            this.CheckErrors(await this.UserManager.RemoveFromRoleAsync(userId, roleName));
        }

        /// <inheritDoc/>
        public async Task<ListResultDto<UserEntityDto>> GetUsers()
        {
            var users = await this.UserRepository.GetAllListAsync();
            return new ListResultDto<UserEntityDto>(users.MapTo<List<UserEntityDto>>());
        }

        /// <inheritDoc/>
        public async Task CreateUser(CreateUserInputDto input)
        {
            var user = input.MapTo<User>();

            user.TenantId = this.AbpSession.TenantId;
            user.Password = new PasswordHasher().HashPassword(User.DefaultPassword);
            user.IsActive = true;
            user.IsEmailConfirmed = true;

            this.CheckErrors(await this.UserManager.CreateAsync(user));
        }
       
        /// <inheritDoc/>
        public async Task<UserEntityDto> GetUser(long id)
        {
            var user = await this.UserManager.GetUserByIdAsync(id);
            return user.MapTo<UserEntityDto>();
        }

        /// <inheritDoc/>
        public async Task UpdateUser(UpdateUserInput input)
        {
            var user = await this.UserManager.GetUserByIdAsync(input.Id);
            user = input.MapTo(user);
            this.CheckErrors(await this.UserManager.UpdateAsync(user));
        }

        /// <inheritDoc/>
        public async Task DeleteUser(UserInput input)
        {
            var user = await this.UserManager.GetUserByIdAsync(input.Id);
            this.CheckErrors(await this.UserManager.DeleteAsync(user));
        }

        /// <inheritDoc/>
        public async Task EnableUser(UserInput input)
        {
            var user = await this.UserManager.GetUserByIdAsync(input.Id);
            user.IsActive = true;
            this.CheckErrors(await this.UserManager.UpdateAsync(user));
        }

        /// <inheritDoc/>
        public async Task DisableUser(UserInput input)
        {
            var user = await this.UserManager.GetUserByIdAsync(input.Id);
            user.IsActive = false;
            this.CheckErrors(await this.UserManager.UpdateAsync(user));
        }

        /// <inheritDoc/>
        public async Task ResetUserPassword(UserInput input)
        {
            var user = await this.UserManager.GetUserByIdAsync(input.Id);
            user.Password = new PasswordHasher().HashPassword(User.DefaultPassword);
            this.CheckErrors(await this.UserManager.UpdateAsync(user));
        }
        /// <inheritDoc/>
        public async Task CreateShopUserInput(CreateShopUserInput input)
        {
            var user = input.MapTo<User>();
            await this.UserRepository.InsertAsync(user);
        }
    }
}